// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------
// Modification history:
// feature: listener code decoupling
// feature: Unified Transport Abstraction Layer Unified Transport Abstraction Layer
// feature: Add xcdrv2, mutable, optional, id, and their test cases
// feature: the default memory policy change from PREALLOCATED_MEMORY_MODE to PREALLOCATED_WITH_REALLOC_MEMORY_MODE
// feature: destination order support by reception timestamp
// feature: support batch send
// feature: E2E Profile04 and Configuration Function Development
// feature: flowcontroller xml config and writer/reader-resourcelimit
// ------------------------------------------------------------------

#ifndef INCLUDE_EDDS_DDS_CORE_POLICY_QOSPOLICIES_HPP_
#define INCLUDE_EDDS_DDS_CORE_POLICY_QOSPOLICIES_HPP_

#include <edds/rtps/attributes/PropertyPolicy.h>
#include <edds/rtps/common/Types.h>
#include <edds/rtps/common/Time_t.h>
#include <edds/rtps/resources/ResourceManagement.h>
#include <ertps/types/TypeObject.h>

#include <vector>
#include <string>
#include <edds/dds/core/policy/ParameterTypes.hpp>

#include <edds/rtps/attributes/ExternalLocators.hpp>
#include <edds/rtps/attributes/RTPSParticipantAllocationAttributes.hpp>
#include <edds/rtps/attributes/RTPSParticipantAttributes.h>
#include <deps/common/LocatorList.hpp>
#include <edds/rtps/flowcontrol/FlowControllerConsts.hpp>
#include <ertps/utils/collections/ResourceLimitedVector.hpp>

#include <xmlparser/qos/XMLQosPolicies.hpp>
// #include <transport/TransportDescriptorInterface.h>
namespace evbs {
namespace edds {
namespace dds {

using vbsutil::xmlparser::LENGTH_UNLIMITED;

using vbsutil::xmlparser::QosPolicyId_t;
using vbsutil::xmlparser::QosPolicyId_t::BATCHSEND_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::DEADLINE_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::DESTINATIONORDER_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::DISABLEPOSITIVEACKS_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::DURABILITY_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::DURABILITYSERVICE_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::ENTITYFACTORY_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::GROUPDATA_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::HISTORY_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::INVALID_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::LATENCYBUDGET_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::LIFESPAN_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::LIVELINESS_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::NEXT_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::OWNERSHIP_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::OWNERSHIPSTRENGTH_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::PARTICIPANTRESOURCELIMITS_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::PARTITION_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::PRESENTATION_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::PROPERTYPOLICY_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::PUBLISHMODE_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::READERDATALIFECYCLE_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::READERE2EPR04DATAID_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::READERE2EPR04MAXDATALENGTH_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::READERE2EPR04MAXDELTACOUNTER_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::READERE2EPR04MINDATALENGTH_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::READERE2EPROTECTION_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::READERRESOURCELIMITS_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::RELIABILITY_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::RESOURCELIMITS_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::RTPSENDPOINT_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::RTPSRELIABLEREADER_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::RTPSRELIABLEWRITER_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::TIMEBASEDFILTER_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::TOPICDATA_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::TRANSPORTCONFIG_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::TRANSPORTPRIORITY_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::USERDATA_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::WIREPROTOCOLCONFIG_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::WRITERDATALIFECYCLE_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::WRITERE2EPR04DATAID_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::WRITERE2EPR04MAXDATALENGTH_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::WRITERE2EPR04MAXDELTACOUNTER_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::WRITERE2EPR04MINDATALENGTH_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::WRITERE2EPROTECTION_QOS_POLICY_ID;
using vbsutil::xmlparser::QosPolicyId_t::WRITERRESOURCELIMITS_QOS_POLICY_ID;

using vbsutil::xmlparser::PolicyMask;
using QosPolicy = vbsutil::xmlparser::QosPolicy;
using DurabilityQosPolicyKind = vbsutil::xmlparser::DurabilityQosPolicyKind;
using vbsutil::xmlparser::DurabilityQosPolicyKind_t;
using vbsutil::xmlparser::DurabilityQosPolicyKind_t::PERSISTENT_DURABILITY_QOS;
using vbsutil::xmlparser::DurabilityQosPolicyKind_t::TRANSIENT_DURABILITY_QOS;
using vbsutil::xmlparser::DurabilityQosPolicyKind_t::TRANSIENT_LOCAL_DURABILITY_QOS;
using vbsutil::xmlparser::DurabilityQosPolicyKind_t::VOLATILE_DURABILITY_QOS;
using DurabilityQosPolicy = vbsutil::xmlparser::DurabilityQosPolicy;
using DeadlineQosPolicy = vbsutil::xmlparser::DeadlineQosPolicy;
using BatchQosPolicy = vbsutil::xmlparser::BatchQosPolicy;

using LivelinessQosPolicyKind = vbsutil::xmlparser::LivelinessQosPolicyKind;
using vbsutil::xmlparser::LivelinessQosPolicyKind::AUTOMATIC_LIVELINESS_QOS;
using vbsutil::xmlparser::LivelinessQosPolicyKind::MANUAL_BY_PARTICIPANT_LIVELINESS_QOS;
using vbsutil::xmlparser::LivelinessQosPolicyKind::MANUAL_BY_TOPIC_LIVELINESS_QOS;
using LivelinessQosPolicy = vbsutil::xmlparser::LivelinessQosPolicy;

using ReliabilityQosPolicyKind = vbsutil::xmlparser::ReliabilityQosPolicyKind;
using vbsutil::xmlparser::ReliabilityQosPolicyKind::BEST_EFFORT_RELIABILITY_QOS;
using vbsutil::xmlparser::ReliabilityQosPolicyKind::RELIABLE_RELIABILITY_QOS;

using ReliabilityQosPolicy = vbsutil::xmlparser::ReliabilityQosPolicy;

using OwnershipQosPolicyKind = vbsutil::xmlparser::OwnershipQosPolicyKind;
using vbsutil::xmlparser::OwnershipQosPolicyKind::EXCLUSIVE_OWNERSHIP_QOS;
using vbsutil::xmlparser::OwnershipQosPolicyKind::SHARED_OWNERSHIP_QOS;

using OwnershipQosPolicy = vbsutil::xmlparser::OwnershipQosPolicy;

using Partition_t = vbsutil::xmlparser::Partition_t;

using PartitionQosPolicy = vbsutil::xmlparser::PartitionQosPolicy;

using HistoryQosPolicyKind = vbsutil::xmlparser::HistoryQosPolicyKind;
using vbsutil::xmlparser::HistoryQosPolicyKind::KEEP_ALL_HISTORY_QOS;
using vbsutil::xmlparser::HistoryQosPolicyKind::KEEP_LAST_HISTORY_QOS;

using HistoryQosPolicy = vbsutil::xmlparser::HistoryQosPolicy;

using ResourceLimitsQosPolicy = vbsutil::xmlparser::ResourceLimitsQosPolicy;

using LifespanQosPolicy = vbsutil::xmlparser::LifespanQosPolicy;

using OwnershipStrengthQosPolicy = vbsutil::xmlparser::OwnershipStrengthQosPolicy;

using PublishModeQosPolicyKind = vbsutil::xmlparser::PublishModeQosPolicyKind;
using vbsutil::xmlparser::PublishModeQosPolicyKind_t::ASYNCHRONOUS_PUBLISH_MODE;
using vbsutil::xmlparser::PublishModeQosPolicyKind_t::SYNCHRONOUS_PUBLISH_MODE;

using DataRepresentationId_t = vbsutil::xmlparser::DataRepresentationId_t;
//! Default @ref DataRepresentationId used in EVBS.
constexpr DataRepresentationId_t DEFAULT_DATA_REPRESENTATION {DataRepresentationId_t::XCDR_DATA_REPRESENTATION};

using PublishModeQosPolicy = vbsutil::xmlparser::PublishModeQosPolicy;

using TypeConsistencyKind = vbsutil::xmlparser::TypeConsistencyKind;
using vbsutil::xmlparser::TypeConsistencyKind::ALLOW_TYPE_COERCION;
using vbsutil::xmlparser::TypeConsistencyKind::DISALLOW_TYPE_COERCION;

using TypeConsistencyEnforcementQosPolicy = vbsutil::xmlparser::TypeConsistencyEnforcementQosPolicy;

using DisablePositiveACKsQosPolicy = vbsutil::xmlparser::DisablePositiveACKsQosPolicy;

using E2EProtectionQosPolicy = vbsutil::xmlparser::E2EProtectionQosPolicy;

using ParticipantResourceLimitsQos = vbsutil::xmlparser::RTPSParticipantAllocationAttributes;

using PropertyPolicyQos = vbsutil::xmlparser::PropertyPolicyQos;

using WireProtocolConfigQos = vbsutil::xmlparser::WireProtocolConfigQos;

//! Qos Policy to configure the transport layer
class TransportConfigQos : public QosPolicy {
 public:
    /**
     * @brief Constructor
     */
    RTPS_DllAPI TransportConfigQos()
        : QosPolicy(), use_builtin_transports(true), send_socket_buffer_size(0U), listen_socket_buffer_size(0U) {}

    /**
     * @brief Destructor
     */
    virtual RTPS_DllAPI ~TransportConfigQos() = default;

    bool operator==(const TransportConfigQos& b) const {
        return (this->user_transports == b.user_transports) &&
               (this->use_builtin_transports == b.use_builtin_transports) &&
               (this->send_socket_buffer_size == b.send_socket_buffer_size) &&
               (this->listen_socket_buffer_size == b.listen_socket_buffer_size) && (QosPolicy::operator==(b));
    }

    inline void clear() override {
        TransportConfigQos reset = TransportConfigQos();
        std::swap(*this, reset);
    }

    //! User defined transports to use alongside or in place of builtins.
    std::vector<std::shared_ptr<vbs::transport::TransportDescriptorInterface>> user_transports;

    //! Set as false to disable the default UDPv4 implementation. <br> By default, true.
    bool use_builtin_transports;

    ertps::rtps::TransportTypeKind transport_type = ertps::rtps::TRANSPORT_TYPE_UDP;

    /*!
     * @brief Send socket buffer size for the send resource. Zero value indicates to use default
     * system buffer size. <br> By default, 0.
     */
    uint32_t send_socket_buffer_size;

    /*! Listen socket buffer for all listen resources. Zero value indicates to use default system
     * buffer size. <br> By default, 0.
     */
    uint32_t listen_socket_buffer_size;
};

using RTPSEndpointQos = vbsutil::xmlparser::RTPSEndpointQos;

using WriterResourceLimitsQos = vbsutil::xmlparser::WriterResourceLimitsQos;

using DestinationOrderQosPolicyKind = vbsutil::xmlparser::DestinationOrderQosPolicyKind;
using vbsutil::xmlparser::DestinationOrderQosPolicyKind::BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS;
using vbsutil::xmlparser::DestinationOrderQosPolicyKind::BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS;

using DestinationOrderQosPolicy = vbsutil::xmlparser::DestinationOrderQosPolicy;

}  // namespace dds
}  // namespace edds
}  // namespace evbs

#endif  // INCLUDE_EDDS_DDS_CORE_POLICY_QOSPOLICIES_HPP_
